﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WT.Sockert.Heads;
using WT.Sockert.Interfaces;

namespace WT.Sockert {
    public class SocketConnection : ISocketConnection {

        private const int ReadSize = 1024 * 4;
        public ISocket Socket { get; set; }

        private SocketParser sParser { get; set; }
      
        public SocketConnection(ISocket socket, Action<ISocketConnection> initialize) {
            Socket = socket;
            OnOpen = () => { };
            OnClose = () => { };
            OnMessage = x => { };
            OnError = x => { };
            _initialize = initialize;
        }

        public readonly Action<ISocketConnection> _initialize;



        public ISocketConnectionInfo ConnectionInfo {
            get;
        }

        public Action OnClose {
            get;
            set;
        }

        public Action<Exception> OnError {
            get;
            set;
        }

        public Action<string> OnMessage {
            get;
            set;
        }

        public Action OnOpen {
            get;
            set;
        }

        public Task Send(byte[] message) {
            throw new NotImplementedException();
        }
        public bool IsAvailable {
            get { return  Socket.Connected; }
        }

        public string Name {
            get;
            set;
        }

        public void StartReceiving() {
            var data = new List<byte>(ReadSize);
            var buffer = new byte[ReadSize];
            
            Read(data, buffer);
        }
        private void CreateHandler(IEnumerable<byte> data) {
            //转发头信息
            this.Name = Encoding.ASCII.GetString(data.ToArray());
            sParser = new SocketParser();
            sParser.ReceiveData = (e) => {
                OnMessage(Encoding.ASCII.GetString(e.ToArray(), 0, e.ToArray().Length));
            };
            _initialize(this);
            byte[] handshake = new byte[0];
            SendBytes(handshake, OnOpen);

        }
        private Task SendBytes(byte[] bytes, Action callback = null) {
            return Socket.Send(bytes, () =>
            {
                
                if (callback != null)
                    callback();
            }, e => {
                Console.WriteLine(e.Message);
            });
        }

        private void Read(List<byte> data, byte[] buffer) {
            if (!IsAvailable)
                return;

            Socket.Receive(buffer, r =>
            {
                var readBytes = buffer.Take(r);
                if (sParser != null) {
                    sParser.Receive(readBytes);
                } else {
                    data.AddRange(readBytes);
                    CreateHandler(data);
                }

                Read(data, buffer);
            },
            (error)=> {
                Console.WriteLine(error.Message);
            });
        }
    }
}
